package com.hc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hc.common.bean.PageBean;
import com.hc.constant.CategoryConst;
import com.hc.constant.RedisConst;
import com.hc.constant.SkuConst;
import com.hc.domain.Category;
import com.hc.domain.Sku;
import com.hc.mapper.SkuMapper;
import com.hc.res.CategoryItem;
import com.hc.res.CategoryWithSku;
import com.hc.res.Entry;
import com.hc.res.SkuDetail;
import com.hc.res.SkuItem;
import com.hc.service.CategoryService;
import com.hc.service.SkuService;
import com.hc.trans.CategoryTrans;
import com.hc.trans.SkuTrans;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author hecai
 * @date 2021/12/7 15:10
 */
@Service
@CacheConfig(cacheManager = "cacheManager")
public class SkuServiceImpl extends ServiceImpl<SkuMapper, Sku> implements SkuService {

    @Override
    @Cacheable(value = RedisConst.Index.name, key = "#key", condition = "#flag==true")
    public List<Entry<Integer, String>> selectAds(Integer amount, Integer type, String key, Boolean flag) {
        IPage<Sku> page = new Page<>(1, amount);
        QueryWrapper<Sku> queryWrapper = new QueryWrapper<Sku>()
                .select("id", "img")
                .eq("type", type)
                .eq("status", SkuConst.Status.ok)
                .orderByDesc("priority");
        baseMapper.selectPage(page, queryWrapper);

        List<Sku> skuList = page.getRecords();
        List<Entry<Integer, String>> res = new ArrayList<>();
        for (Sku sku : skuList) {
            Entry<Integer, String> entry = new Entry<>(sku.getId(), sku.getImg());
            res.add(entry);
        }
        //Map<Integer, String> res = skuList.stream().collect(Collectors.toMap(Sku::getId, Sku::getImg));
        return res;
    }

    @Override
    @Cacheable(value = RedisConst.Index.name, key = "#key", condition = "#flag==true")
    public List<SkuItem> selectRecommendOrPromotionSku(Integer amount, Integer type, String key, Boolean flag) {
        IPage<Sku> page = new Page<>(1, amount);
        QueryWrapper<Sku> queryWrapper = new QueryWrapper<Sku>()
                .select("id", "name", "specs", "price1", "price2", "img")
                .eq("status", SkuConst.Status.ok)
                .eq("type", SkuConst.Type.COMMON)
                .orderByDesc("priority");
        if (type.equals(SkuConst.Type.Recommend)) {
            queryWrapper.eq("recommend", SkuConst.Recommend.IS);
        } else if (type.equals(SkuConst.Type.Promotion)) {
            queryWrapper.eq("promotion", SkuConst.Promotion.IS);
        }
        baseMapper.selectPage(page, queryWrapper);

        List<Sku> skuList = page.getRecords();
        List<SkuItem> skuItemList = SkuTrans.MAPPER.skuList2skuItemList(skuList);

        return skuItemList;
    }

    @Resource
    private CategoryService categoryService;

    @Override
    @Cacheable(value = RedisConst.Index.name, key = "#key", condition = "#flag==true")
    public List<CategoryWithSku> selectCategoryWidthSku(Integer fatherCategoryAmount, Integer sonCategoryAmount, Integer skuAmount, String key, Boolean flag) {
        List<CategoryWithSku> res = new ArrayList<>();
        //查询类别
        Page<Category> fatherCateogryPage = new Page<>(1, fatherCategoryAmount);
        QueryWrapper<Category> fatherCategoryQueryWrapper = new QueryWrapper<Category>()
                .select("id", "name", "priority", "pid")
                .eq("status", CategoryConst.Status.ok)
                .isNull("pid")
                .orderByDesc("priority");
        categoryService.page(fatherCateogryPage, fatherCategoryQueryWrapper);

        for (Category fatherCategory : fatherCateogryPage.getRecords()) {
            CategoryWithSku categoryWithSku = new CategoryWithSku();
            CategoryItem fatherCategoryItem = CategoryTrans.MAPPER.category2categoryItem(fatherCategory);
            categoryWithSku.setFatherCategory(fatherCategoryItem);
            //查询子类别
            Page<Category> sonCateogryPage = new Page<>(1, sonCategoryAmount);
            QueryWrapper<Category> sonCategoryQueryWrapper = new QueryWrapper<Category>()
                    .select("id", "name", "priority", "pid")
                    .eq("status", CategoryConst.Status.ok)
                    .eq("pid", fatherCategory.getId())
                    .orderByDesc("priority");
            categoryService.page(sonCateogryPage, sonCategoryQueryWrapper);
            List<CategoryItem> sonProductCategoryList = new ArrayList<>();
            //当前父类别下的前sonCategoryAmount条子类别的id的集合
            List<Integer> categoryList = new ArrayList<>();
            for (Category sonCategory : sonCateogryPage.getRecords()) {
                CategoryItem sonCategoryItem = CategoryTrans.MAPPER.category2categoryItem(sonCategory);
                sonProductCategoryList.add(sonCategoryItem);
                categoryList.add(sonCategory.getId());
            }
            categoryWithSku.setSunCategoryList(sonProductCategoryList);

            //查询商品
            Page<Sku> skuPage = new Page<>(1, skuAmount);
            QueryWrapper<Sku> skuQueryWrapper = new QueryWrapper<Sku>()
                    .select("id", "name", "specs", "price1", "price2", "img")
                    .eq("status", CategoryConst.Status.ok)
                    .orderByDesc("priority")
                    .in("category_id", categoryList);
            baseMapper.selectPage(skuPage, skuQueryWrapper);
            List<SkuItem> skuItemList = SkuTrans.MAPPER.skuList2skuItemList(skuPage.getRecords());
            categoryWithSku.setSkuItemList(skuItemList);

            res.add(categoryWithSku);
        }

        return res;
    }

    @Override
    public SkuDetail getSkuDetailBySkuId(Integer id) {
        QueryWrapper<Sku> skuQueryWrapper = new QueryWrapper<>();
        skuQueryWrapper.select("id", "spu_id", "name", "sell_point", "specs", "price1", "price2", "pics", "amount")
                .eq("status", SkuConst.Status.ok)
                .eq("id", id);
        Sku sku = baseMapper.selectOne(skuQueryWrapper);
        SkuDetail skuDetail = SkuTrans.MAPPER.sku2SkuDetail(sku);
        return skuDetail;
    }

    @Override
    public PageBean<SkuItem> getSkuBySpuId(Integer spuId, Integer pageNum, Integer pageSize) {
        Page<Sku> page = new Page<>(pageNum, pageSize);
        baseMapper.selectPage(page, new QueryWrapper<Sku>()
                .select("id", "name", "specs", "price1", "price2", "img")
                .eq("status", SkuConst.Status.ok)
                .orderByDesc("priority")
                .eq("spu_id", spuId));
        PageBean<Sku> skuPageBean = PageBean.init(page);
        PageBean<SkuItem> pageBean = SkuTrans.MAPPER.skuPage2skuItemPage(skuPageBean);
        return pageBean;
    }

    @Override
    public PageBean<SkuItem> getSkusByCategoryPid(Integer pid, Integer pageNum, Integer pageSize) {
        List<Integer> categoryIdList = categoryService.list(new QueryWrapper<Category>().select("id")
                        .eq("pid", pid)
                        .eq("status", CategoryConst.Status.ok))
                .stream()
                .map(item -> item.getId())
                .collect(Collectors.toList());
        Page<Sku> page = new Page<>(pageNum, pageSize);
        baseMapper.selectPage(page, new QueryWrapper<Sku>()
                .select("id", "name", "specs", "price1", "price2", "img")
                .in("category_id", categoryIdList)
                .eq("status", SkuConst.Status.ok)
                .orderByDesc("priority")
        );

        PageBean<Sku> skuPageBean = PageBean.init(page);
        PageBean<SkuItem> skuItemPageBean = SkuTrans.MAPPER.skuPage2skuItemPage(skuPageBean);

        return skuItemPageBean;
    }

    @Override
    public PageBean<SkuItem> getSkusByCategoryId(Integer cid, Integer pageNum, Integer pageSize) {
        Page<Sku> page = new Page<>(pageNum, pageSize);
        baseMapper.selectPage(page, new QueryWrapper<Sku>()
                .select("id", "name", "specs", "price1", "price2", "img")
                .eq("category_id", cid)
                .eq("status", SkuConst.Status.ok)
                .orderByDesc("priority")
        );

        PageBean<Sku> skuPageBean = PageBean.init(page);
        PageBean<SkuItem> skuItemPageBean = SkuTrans.MAPPER.skuPage2skuItemPage(skuPageBean);

        return skuItemPageBean;
    }
}
